<?php
class Map extends ArrayObject
{
	const CONTENT = 'content';
	const INDEX = 'index';
	
	private static $instance = null;
	
	public function __construct() {
		if (DEBUG) {
			$this->read(new SimpleXMLElement(file_get_contents(PATH2ROOT.'map.xml')));
			file_put_contents(PATH2ROOT.'map.dat', serialize((array)$this));
			file_put_contents(PATH2ROOT.'map.json', json_encode((array)$this));
		} else {
			$this->exchangeArray(unserialize(file_get_contents(PATH2ROOT.'map.dat')));
		}
	}
	
	public static function getInstance() {
		if (self::$instance == null) {
			self::$instance = new Map();
		}
		
		return self::$instance;
	}
	
	public function getURI($uri) {
		foreach (array_keys((array)$this) as $curi) {
			if(preg_match('@^'.$curi.'$@', $uri)) {
				return $curi;
			}
		}
		return false;
	}
	
	public function getURIByName($name) {
		foreach ((array)$this as $k => $v) {
			if($v['name'] == $name) {
				return $k;
			}
		}
		
		return false;
	}
	
	private function read($xml, $type=0, $name='', $uri='/', $level=0, $parent='') {
		foreach ($xml as $tag_name => $node) {
			if (!$level) {
				$type = $tag_name;
			}
			
			if (isset($node['uri'])) {
				$curi = $uri.$node['uri'];
				unset($node['uri']);
			}
			
			if (!isset($curi)) {
				if ($tag_name == self::CONTENT && $level == 0) {
					$curi = '/';
				} else {
					$curi = $uri.$tag_name;
				}
			}
			
			if ('_' != $tag_name) {
				$cname = $name.ucfirst($tag_name);
			} else {
				$cname = $name;
			}
			
			$this[$curi] = array();
			
			foreach ($node->attributes() as $attribute_name => $value) {
				if ($attribute_name == 'vars') {
					$this[$curi]['vars'] = explode(',', (string)$value);
				} else {
					$this[$curi][$attribute_name] = (string)$value;
				}
			}
			
			$this[$curi]['name'] = $cname;			
			$this[$curi]['level'] = $level;
			$this[$curi]['type'] = $type;
			$this[$curi]['parent'] = $parent;
			
			if ($level == 1 && $type == self::INDEX) {
				$this[$curi]['includes'] = array();
			}
			
			if ($level == 2 && $type == self::INDEX) {
				$this[substr($uri, 0, -1)]['includes'][] = $curi;
				
				if (!in_array('id', array_keys($this[$curi]))) {
					$this[$curi]['id'] = $tag_name;
				}
			}
			
			if (count((array)$node->children())) {
				$this->read($node->children(), $type, $cname, $curi.(('/'==$curi)?'':'/'), ($level + 1), $curi);
			}
			
			unset($curi);
		}
	}
}
?>